package org.eiahe.hr.attendance.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ehe.common.core.utils.StringUtils;
import org.ehe.system.domain.HrEmployee;
import org.ehe.system.domain.vo.HrEmployeeVo;
import org.ehe.system.service.IHrEmployeeService;
import org.eiahe.hr.attendance.domain.EmployeeAttendanceType;
import org.eiahe.hr.attendance.domain.bo.EmployeeAttendanceTypeBo;
import org.eiahe.hr.attendance.domain.vo.AttendanceTypeVo;
import org.eiahe.hr.attendance.domain.vo.EmployeeAttendanceTypeVo;
import org.eiahe.hr.attendance.mapper.AttendanceTypeMapper;
import org.eiahe.hr.attendance.mapper.EmployeeAttendanceTypeMapper;
import org.eiahe.hr.attendance.service.IAttendanceTypeService;
import org.eiahe.hr.attendance.service.IEmployeeAttendanceTypeService;
import org.ehe.common.core.utils.MapstructUtils;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.*;

/**
 * 员工考勤类型Service业务层处理
 *
 * @author zhangnn
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class EmployeeAttendanceTypeServiceImpl implements IEmployeeAttendanceTypeService {

    private final EmployeeAttendanceTypeMapper baseMapper;
    private final IHrEmployeeService employeeService;
    private final IAttendanceTypeService attendanceTypeService;
    /**
     * 查询员工考勤类型
     */
    @Override
    public EmployeeAttendanceTypeVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询员工考勤类型列表
     */
    @Override
    public TableDataInfo<EmployeeAttendanceTypeVo> queryPageList(EmployeeAttendanceTypeBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EmployeeAttendanceType> lqw = buildQueryWrapper(bo);
        Page<EmployeeAttendanceTypeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        result.getRecords().forEach(p->{
            HrEmployeeVo hrEmployeeVo = employeeService.queryByEmployeeNo(String.valueOf(p.getEmployeeNo()));
            if(Objects.nonNull(hrEmployeeVo)){
                p.setEmployeeName(hrEmployeeVo.getEmployeeName());
            }
            //考勤类型
            AttendanceTypeVo attendanceTypeVo = attendanceTypeService.queryById(p.getTypeId());
            if(Objects.nonNull(attendanceTypeVo)){
                p.setTypeName(attendanceTypeVo.getTypeName());
            }
        });
        return TableDataInfo.build(result);
    }

    /**
     * 查询员工考勤类型列表
     */
    @Override
    public List<EmployeeAttendanceTypeVo> queryList(EmployeeAttendanceTypeBo bo) {
        LambdaQueryWrapper<EmployeeAttendanceType> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoListWithDetails(lqw);
    }

    private LambdaQueryWrapper<EmployeeAttendanceType> buildQueryWrapper(EmployeeAttendanceTypeBo bo) {
        LambdaQueryWrapper<EmployeeAttendanceType> lqw = Wrappers.lambdaQuery();
        //如果名称不能为空
        if (StringUtils.isNotBlank(bo.getEmployeeName())) {
          List<String> employeeNos =  employeeService.queryByEmployeeName(bo.getEmployeeName());
           if(CollUtil.isNotEmpty(employeeNos)){
               lqw.in(EmployeeAttendanceType::getEmployeeNo, employeeNos);
           } else {
               lqw.eq(EmployeeAttendanceType::getEmployeeNo, -1);
           }
        }
        lqw.eq(bo.getUserId() != null, EmployeeAttendanceType::getUserId, bo.getUserId());
        lqw.eq(bo.getTypeId() != null, EmployeeAttendanceType::getTypeId, bo.getTypeId());
        lqw.ge(bo.getEffectiveDate() != null, EmployeeAttendanceType::getEffectiveDate, bo.getEffectiveDate());
        lqw.le(bo.getExpiryDate() != null, EmployeeAttendanceType::getExpiryDate, bo.getExpiryDate());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()),EmployeeAttendanceType::getStatus,bo.getStatus());
        lqw.orderByDesc(EmployeeAttendanceType::getCreateTime);
        return lqw;
    }

    /**
     * 新增员工考勤类型
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByBo(EmployeeAttendanceTypeBo bo) {
        EmployeeAttendanceType add = MapstructUtils.convert(bo, EmployeeAttendanceType.class);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改员工考勤类型
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(EmployeeAttendanceTypeBo bo) {
        EmployeeAttendanceType update = MapstructUtils.convert(bo, EmployeeAttendanceType.class);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 校验并批量删除员工考勤类型信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWithValidByIds(Collection<Long> ids) {
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 批量分配员工考勤类型
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchAssign(EmployeeAttendanceTypeBo bo) {
        if (CollUtil.isEmpty(bo.getEmployeeIds()) && CollUtil.isEmpty(bo.getEmployeeNos())) {
            throw new RuntimeException("员工ID列表或工号列表不能为空");
        }

        List<EmployeeAttendanceType> list = new ArrayList<>();

        List<HrEmployee> empIdList = employeeService.getUserIdByEmployeeNos(bo.getEmployeeNos());
        Map<String, Long> empNoToUserIdMap = new HashMap<>();
        for (HrEmployee emp : empIdList) {
            String empNo = emp.getEmployeeNo();
            Long userId = emp.getUserId();
            empNoToUserIdMap.put(empNo, userId);
        }

        // 如果有employeeNos,使用employeeNos
        if (CollUtil.isNotEmpty(bo.getEmployeeNos())) {
            for (String employeeNo : bo.getEmployeeNos()) {
                Long userId = empNoToUserIdMap.get(employeeNo);
                //去重复
                boolean isDuplicate = list.stream().anyMatch(item -> userId.equals(item.getUserId()));
                if (isDuplicate) continue;
                EmployeeAttendanceType entity = new EmployeeAttendanceType();
                entity.setUserId(userId);
                entity.setEmployeeNo(employeeNo);
                entity.setTypeId(bo.getTypeId());
                entity.setEffectiveDate(bo.getEffectiveDate());
                entity.setExpiryDate(bo.getExpiryDate());
                entity.setStatus(bo.getStatus());
                entity.setRemark(bo.getRemark());
                list.add(entity);
            }
        }

        return baseMapper.insertBatch(list);
    }

    /**
     * 查询员工在指定日期的考勤类型
     */
    @Override
    public EmployeeAttendanceTypeVo queryByEmployeeIdAndDate(Long employeeId, LocalDate date) {
        LambdaQueryWrapper<EmployeeAttendanceType> lqw = Wrappers.lambdaQuery();
        lqw.eq(EmployeeAttendanceType::getUserId, employeeId);
        lqw.le(EmployeeAttendanceType::getEffectiveDate, date);
        lqw.and(wrapper -> wrapper.isNull(EmployeeAttendanceType::getExpiryDate)
                .or()
                .ge(EmployeeAttendanceType::getExpiryDate, date));
        lqw.eq(EmployeeAttendanceType::getStatus, "1");
        lqw.orderByDesc(EmployeeAttendanceType::getEffectiveDate);
        lqw.last("LIMIT 1");

        List<EmployeeAttendanceTypeVo> list = baseMapper.selectVoListWithDetails(lqw);
        return CollUtil.isEmpty(list) ? null : list.get(0);
    }
}
